package model.stats;

/**
 * 
 * @author srhinson
 *added leveling methods for stats.  current get methods return int values, not stat objects and cannot be leveled.
 */
public class StatsContainer {

	private Stat strength;
	private Stat agility;
	private Stat intellect;
	private Stat hardiness;
	private Stat movement;
	private Stat visionRange;
	private StatMods maxHealth;
	private StatMods maxMana;
	private StatMods offenseRating;
	private StatMods defenseRating;
	private StatMods armorRating;
	private int currentHealth;
	private int currentMana;
	private int experience;
	private int lives;
	
	public StatsContainer(){
		strength=new Stat("str", 1);
		agility=new Stat("agi", 1);
		intellect=new Stat("int",1);
		hardiness=new Stat("hard",1);
		movement=new Stat("move",1);
		maxHealth=new StatMods();
		maxMana=new StatMods();
		offenseRating=new StatMods();
		defenseRating=new StatMods();
		armorRating=new StatMods();
		currentHealth=getMaxHealth();
		currentMana=getMaxMana();
		experience=0;
		lives=3;
	}
	public StatsContainer(int str, int agi, int intel, int hard, int move,int exp, int lives){
		strength=new Stat("str", str);
		agility=new Stat("agi", agi);
		intellect=new Stat("int",intel);
		hardiness=new Stat("hard",hard);
		movement=new Stat("move",move);
		maxHealth=new StatMods();
		maxMana=new StatMods();
		offenseRating=new StatMods();
		defenseRating=new StatMods();
		armorRating=new StatMods();
		currentHealth=getMaxHealth();
		currentMana=getMaxMana();
		experience=exp;
		this.lives=lives;
	}
	public int getStrength() {
		return strength.getValue();
	}
	public int getAgility() {
		return agility.getValue();
	}
	public int getIntellect() {
		return intellect.getValue();
	}
	public int getHardiness(){
		return hardiness.getValue();
	}
	public void levelStrength(int i) {
		strength.increment(i);
	}
	public void levelAgility(int i) {
		agility.increment(i);
	}
	public void levelIntellect(int i) {
		strength.increment(i);
	}
	public void levelHardiness(int i){
		hardiness.increment(i);
	}
	public int getMovement(){
		return movement.getValue();
	}
	public int getMaxHealth(){
		int result = 500+100*(getHardiness() + getLevel());
		return maxHealth.modify(result);
	}
	public int getMaxMana(){
		int result = 500+100*(getIntellect() + getLevel());
		return maxMana.modify(result);
	}
	public int getCurrentHealth() {
		return currentHealth;
	}
	public int getCurrentMana() {
		return currentMana;
	}
	public int getOffenseRating() {
		int result = 3*(2*getStrength()+ getLevel());
		return offenseRating.modify(result);
	}
	public int getDefenseRating() {
		int result=  3*(2*getAgility()+ getLevel());
		return defenseRating.modify(result);
	}
	public int getArmorRating(){
		int result = 3*(2*getHardiness()+ getLevel());
		return armorRating.modify(result);
	}
	public int getExperience(){
		return experience;
	}
	public int getLevel() {
		return getExperience()/500;
	}
	public int getLives(){
		return lives;
	}
	public int getVisionRange(){
		return visionRange.getValue();
	}
	
	public void setLives(int value){
		lives = value;
	}
	public void gainLives(int amount){
		lives+= amount;
	}
	public void setHealth(int health){
		currentHealth = health;
	}
	public void setMana(int mana){
		currentMana = mana;
	}
	
	public void addStatsTempMods(StatsTempMods mods){
		mods.apply(this);
	}
	public void addStatsPersistMods(StatsPersistMods mods){
		mods.apply(this);
	}
	public void removeStatsPersistMods(StatsPersistMods mods){
		mods.remove(this);
	}

	public void addTempModStrength(int amount, int duration) {
		strength.addTempMod(amount,duration);
	}
	public void addTempModAgility(int amount, int duration) {
		agility.addTempMod(amount,duration);
	}
	public void addTempModIntellect(int amount, int duration) {
		intellect.addTempMod(amount,duration);
	}
	public void addTempModHardiness(int amount, int duration) {
		hardiness.addTempMod(amount,duration);
	}
	public void addTempModMovement(int amount, int duration) {
		movement.addTempMod(amount,duration);
	}
	public void addTempModMaxHealth(int amount, int duration) {
		maxHealth.addTempMod(amount,duration);
		assertCurrentHealthLimit();
	}
	public void addTempModMaxMana(int amount, int duration) {
		maxMana.addTempMod(amount,duration);
		assertCurrentManaLimit();
	}
	public void addTempModOffense(int amount, int duration) {
		offenseRating.addTempMod(amount,duration);
	}
	public void addTempModDefense(int amount, int duration) {
		defenseRating.addTempMod(amount,duration);
	}
	public void addTempModArmor(int amount, int duration) {
		armorRating.addTempMod(amount,duration);
	}
	public void addTempModVision(int amount, int duration){
		visionRange.addTempMod(amount, duration);
	}

	public void addPersistModStrength(int amount) {
		strength.addPersistMod(amount);
	}
	public void addPersistModAgility(int amount) {
		agility.addPersistMod(amount);
	}
	public void addPersistModIntellect(int amount) {
		intellect.addPersistMod(amount);
	}
	public void addPersistModHardiness(int amount) {
		hardiness.addPersistMod(amount);
	}
	public void addPersistModMovement(int amount) {
		movement.addPersistMod(amount);
	}
	public void addPersistModMaxHealth(int amount) {
		maxHealth.addPersistMod(amount);
		assertCurrentHealthLimit();
	}
	public void addPersistModMaxMana(int amount) {
		maxMana.addPersistMod(amount);
		assertCurrentManaLimit();
	}
	public void addPersistModOffense(int amount) {
		offenseRating.addPersistMod(amount);
	}
	public void addPersistModDefense(int amount) {
		defenseRating.addPersistMod(amount);
	}
	public void addPersistModArmor(int amount) {
		armorRating.addPersistMod(amount);
	}
	public void addPersistModVision(int amount){
		visionRange.addPersistMod(amount);
	}
	private void assertCurrentHealthLimit(){
		if(getCurrentHealth() > getMaxHealth()){
			setHealth(getMaxHealth());
		}
		else if (getCurrentHealth()<0)setHealth(0);
	}
	private void assertCurrentManaLimit(){
		if(getCurrentMana() > getMaxMana()){
			setHealth(getMaxMana());
		}
		else if (getCurrentMana()<0)setMana(0);
	}
	public void update() {
		strength.update();
		agility.update();
		intellect.update();
		hardiness.update();
		movement.update();
		maxHealth.update();
		maxMana.update();
		offenseRating.update();
		defenseRating.update();
		armorRating.update();
		
	}
	public void gainExp(int exp){
		experience=experience+exp;
	}
	
	public void gainHealth(int amount){
		setHealth(getCurrentHealth()+amount);
		assertCurrentHealthLimit();
	}
	public void loseHealth(int amount) {
		setHealth(getCurrentHealth()+amount);
		assertCurrentHealthLimit();
	}
	public void gainMana(int amount) {
		setMana(getCurrentMana()+amount);
		assertCurrentManaLimit();
	}
	public void loseMana(int amount) {
		setMana(getCurrentMana()-amount);
		assertCurrentManaLimit();
	}
	
}
